//! # RustCloud 配置管理模块
//!
//! 该模块提供了 RustCloud 微服务框架的统一配置管理功能，支持多种配置格式和来源。
//! 包含了应用、注册中心、负载均衡、熔断器、传输层、日志和网关等所有组件的配置。
//!
//! ## 配置特性
//!
//! * **多格式支持** - 支持 TOML、YAML、JSON 三种配置格式
//! * **配置验证** - 提供配置有效性验证功能
//! * **序列化/反序列化** - 支持配置的持久化和加载
//! * **示例配置** - 提供开箱即用的示例配置
//! * **类型安全** - 使用 Rust 类型系统确保配置正确性
//!
//! ## 支持的配置组件
//!
//! * **应用配置** - 服务名称、版本、端口等基础信息
//! * **注册中心配置** - Nacos、Consul、Eureka 等注册中心设置
//! * **负载均衡配置** - 轮询、随机、加权等负载均衡策略
//! * **熔断器配置** - 服务保护和故障隔离设置
//! * **传输配置** - 超时、重试、连接池等网络传输参数
//! * **日志配置** - 日志级别、格式、输出目标等设置
//! * **网关配置** - 路由规则、过滤器、认证等网关功能
//!
//! ## 使用示例
//!
//! ```rust,no_run
//! use rustcloud_config::RustCloudConfig;
//!
//! # fn main() -> Result<(), String> {
//! // 从配置文件加载
//! let config = RustCloudConfig::from_file("config.yaml")?;
//!
//! // 验证配置
//! config.validate()?;
//!
//! // 保存配置到文件
//! config.save_to_file("output.toml")?;
//!
//! // 创建示例配置
//! let example = RustCloudConfig::create_example_config();
//! # Ok(())
//! # }
//! ```

// 注意：这些配置现在应该在各自的专门模块中定义，改为导入而不是本地定义
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

// 从专门模块导入配置，避免重复定义
// 注意：这些导入可能需要根据专门模块的实际导出进行调整
// pub use rustcloud_registry::RegistryConfig;
// pub use rustcloud_loadbalancer::LoadBalancerConfig;
// pub use rustcloud_circuit_breaker::CircuitBreakerConfig;
// pub use rustcloud_transport::TransportConfig;
// pub use rustcloud_logging::LoggingConfig;
// pub use rustcloud_gateway::GatewayConfig;

// 临时保留配置定义，待专门模块完善后移除
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ApplicationConfig {
    pub name: String,
    pub version: String,
    pub port: u16,
    pub description: Option<String>,
    pub tags: HashMap<String, String>,
}

impl Default for ApplicationConfig {
    fn default() -> Self {
        Self {
            name: "rustcloud-app".to_string(),
            version: "1.0.0".to_string(),
            port: 8080,
            description: None,
            tags: HashMap::new(),
        }
    }
}

/// 临时注册中心配置（重复定义！）
/// TODO: 应该使用 rustcloud-registry::RegistryConfig 而不是重新定义
#[derive(Debug, Clone, Serialize, Deserialize)]
#[deprecated(note = "请使用 rustcloud-registry 模块中的 RegistryConfig")]
pub struct RegistryConfig {
    pub registry_type: String,
    pub server_addr: String,
    pub namespace: Option<String>,
    pub group: Option<String>,
}

impl Default for RegistryConfig {
    fn default() -> Self {
        Self {
            registry_type: "nacos".to_string(),
            server_addr: "127.0.0.1:8848".to_string(),
            namespace: None,
            group: None,
        }
    }
}

/// 临时负载均衡配置（重复定义！）
/// TODO: 应该使用 rustcloud-loadbalancer::LoadBalancerConfig 而不是重新定义
#[derive(Debug, Clone, Serialize, Deserialize)]
#[deprecated(note = "请使用 rustcloud-loadbalancer 模块中的相关配置")]
pub struct LoadBalancerConfig {
    pub strategy: String,
    pub health_check_enabled: bool,
}

impl Default for LoadBalancerConfig {
    fn default() -> Self {
        Self {
            strategy: "round_robin".to_string(),
            health_check_enabled: true,
        }
    }
}

/// 临时熔断器配置（重复定义！）
/// TODO: 应该使用 rustcloud-circuit-breaker::CircuitBreakerConfig 而不是重新定义
#[derive(Debug, Clone, Serialize, Deserialize)]
#[deprecated(note = "请使用 rustcloud-circuit-breaker 模块中的 CircuitBreakerConfig")]
pub struct CircuitBreakerConfig {
    pub enabled: bool,
    pub failure_threshold: u32,
    pub timeout_duration: u64,
    pub recovery_timeout: u64,
}

impl Default for CircuitBreakerConfig {
    fn default() -> Self {
        Self {
            enabled: true,
            failure_threshold: 5,
            timeout_duration: 60,
            recovery_timeout: 30,
        }
    }
}

/// 临时传输层配置（重复定义！）
/// TODO: 应该使用 rustcloud-transport::TransportConfig 而不是重新定义
#[derive(Debug, Clone, Serialize, Deserialize)]
#[deprecated(note = "请使用 rustcloud-transport 模块中的 TransportConfig")]
pub struct TransportConfig {
    pub timeout: u64,
    pub max_retries: u32,
    pub connection_pool_size: u32,
}

impl Default for TransportConfig {
    fn default() -> Self {
        Self {
            timeout: 5000,
            max_retries: 3,
            connection_pool_size: 100,
        }
    }
}

/// 临时日志配置（重复定义！）
/// TODO: 应该使用 rustcloud-logging::LoggingConfig 而不是重新定义
#[derive(Debug, Clone, Serialize, Deserialize)]
#[deprecated(note = "请使用 rustcloud-logging 模块中的 LoggingConfig")]
pub struct LoggingConfig {
    pub level: String,
    pub format: String,
    pub output: String,
}

impl Default for LoggingConfig {
    fn default() -> Self {
        Self {
            level: "info".to_string(),
            format: "json".to_string(),
            output: "console".to_string(),
        }
    }
}

/// 临时网关配置（重复定义！）
/// TODO: 应该使用 rustcloud-gateway::GatewayConfig 而不是重新定义
#[derive(Debug, Clone, Serialize, Deserialize)]
#[deprecated(note = "请使用 rustcloud-gateway 模块中的 GatewayConfig")]
pub struct GatewayConfig {
    pub server_addr: String,
    pub routes: Vec<RouteConfig>,
    pub filters: FilterConfig,
}

impl Default for GatewayConfig {
    fn default() -> Self {
        Self {
            server_addr: "0.0.0.0:8080".to_string(),
            routes: Vec::new(),
            filters: FilterConfig::default(),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FilterConfig {
    pub auth: AuthFilterConfig,
    pub rate_limit: RateLimitConfig,
}

impl Default for FilterConfig {
    fn default() -> Self {
        Self {
            auth: AuthFilterConfig::default(),
            rate_limit: RateLimitConfig::default(),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthFilterConfig {
    pub enabled: bool,
    pub api_key_required: bool,
}

impl Default for AuthFilterConfig {
    fn default() -> Self {
        Self {
            enabled: false,
            api_key_required: false,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RateLimitConfig {
    pub enabled: bool,
    pub requests_per_minute: u32,
    pub burst_size: u32,
}

impl Default for RateLimitConfig {
    fn default() -> Self {
        Self {
            enabled: false,
            requests_per_minute: 1000,
            burst_size: 100,
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RouteConfig {
    pub path_prefix: String,
    pub service_name: String,
    pub rewrite_path: bool,
    pub enable_cache: bool,
    pub cache_ttl: u64,
}

impl RouteConfig {
    pub fn new(path_prefix: String, service_name: String) -> Self {
        Self {
            path_prefix,
            service_name,
            rewrite_path: false,
            enable_cache: false,
            cache_ttl: 300,
        }
    }
}
use std::fs;
use std::path::Path;

/// RustCloud 完整配置结构
///
/// 统一管理 RustCloud 微服务框架的所有组件配置。该结构体包含了运行一个完整的
/// 微服务应用所需的全部配置信息，支持多种序列化格式和配置验证。
///
/// # 配置组织
///
/// 配置按功能模块组织，每个模块都有独立的配置结构和默认值：
///
/// * **应用层配置** - 基础的应用信息和运行参数
/// * **基础设施配置** - 注册中心、负载均衡、熔断器等
/// * **网络传输配置** - 超时、重试、连接管理等
/// * **可观测性配置** - 日志、指标、追踪等
/// * **网关配置** - 路由、过滤器、认证等
///
/// # 配置格式支持
///
/// * **TOML** - 人类友好的配置格式，适合手工编辑
/// * **YAML** - 层次清晰的配置格式，支持复杂结构
/// * **JSON** - 标准的数据交换格式，便于程序生成
///
/// # 配置验证
///
/// 提供完整的配置验证功能，确保：
/// * 必需字段不为空
/// * 数值范围合理
/// * 网络地址格式正确
/// * 路由配置有效
///
/// # 使用场景
///
/// * **开发环境** - 快速配置本地开发环境
/// * **测试环境** - 配置测试所需的各种参数
/// * **生产环境** - 管理复杂的生产配置
/// * **配置管理** - 集中管理多个环境的配置差异
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RustCloudConfig {
    /// 应用基础配置
    pub application: ApplicationConfig,
    /// 服务注册中心配置
    pub registry: RegistryConfig,
    /// 负载均衡器配置
    pub loadbalancer: LoadBalancerConfig,
    /// 熔断器配置
    pub circuit_breaker: CircuitBreakerConfig,
    /// 网络传输层配置
    pub transport: TransportConfig,
    /// 日志系统配置
    pub logging: LoggingConfig,
    /// API 网关配置
    pub gateway: GatewayConfig,
}

impl Default for RustCloudConfig {
    fn default() -> Self {
        Self {
            application: ApplicationConfig::default(),
            registry: RegistryConfig::default(),
            loadbalancer: LoadBalancerConfig::default(),
            circuit_breaker: CircuitBreakerConfig::default(),
            transport: TransportConfig::default(),
            logging: LoggingConfig::default(),
            gateway: GatewayConfig::default(),
        }
    }
}

impl RustCloudConfig {
    /// 从配置文件加载配置
    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, String> {
        let content = fs::read_to_string(&path)
            .map_err(|e| format!("Failed to read config file: {}", e))?;
        
        // 根据文件扩展名选择解析器
        let path_ref = path.as_ref();
        let extension = path_ref.extension()
            .and_then(|ext| ext.to_str())
            .unwrap_or("");
        
        match extension.to_lowercase().as_str() {
            "toml" => Self::from_toml(&content),
            "yaml" | "yml" => Self::from_yaml(&content),
            "json" => Self::from_json(&content),
            _ => Self::from_yaml(&content), // 默认使用YAML
        }
    }

    /// 从TOML字符串加载配置
    pub fn from_toml(toml: &str) -> Result<Self, String> {
        toml::from_str(toml)
            .map_err(|e| format!("Failed to parse TOML config: {}", e))
    }

    /// 从JSON字符串加载配置
    pub fn from_json(json: &str) -> Result<Self, String> {
        serde_json::from_str(json)
            .map_err(|e| format!("Failed to parse JSON config: {}", e))
    }

    /// 从YAML字符串加载配置
    pub fn from_yaml(yaml: &str) -> Result<Self, String> {
        serde_yaml::from_str(yaml)
            .map_err(|e| format!("Failed to parse YAML config: {}", e))
    }

    /// 保存配置到文件
    pub fn save_to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), String> {
        let path_ref = path.as_ref();
        let extension = path_ref.extension()
            .and_then(|ext| ext.to_str())
            .unwrap_or("");
        
        let content = match extension.to_lowercase().as_str() {
            "toml" => self.to_toml()?,
            "yaml" | "yml" => self.to_yaml()?,
            "json" => self.to_json()?,
            _ => self.to_yaml()?, // 默认使用YAML
        };
        
        fs::write(path, content)
            .map_err(|e| format!("Failed to write config file: {}", e))
    }

    /// 转为TOML格式
    pub fn to_toml(&self) -> Result<String, String> {
        toml::to_string_pretty(self)
            .map_err(|e| format!("Failed to serialize to TOML: {}", e))
    }

    /// 转为YAML格式
    pub fn to_yaml(&self) -> Result<String, String> {
        serde_yaml::to_string(self)
            .map_err(|e| format!("Failed to serialize to YAML: {}", e))
    }

    /// 转为JSON格式
    pub fn to_json(&self) -> Result<String, String> {
        serde_json::to_string_pretty(self)
            .map_err(|e| format!("Failed to serialize to JSON: {}", e))
    }

    /// 验证配置
    pub fn validate(&self) -> Result<(), String> {
        // 验证应用配置
        if self.application.name.is_empty() {
            return Err("Application name cannot be empty".to_string());
        }

        // 验证注册中心配置
        if self.registry.server_addr.is_empty() {
            return Err("Registry server address cannot be empty".to_string());
        }

        // 验证网关配置
        if self.gateway.server_addr.is_empty() {
            return Err("Gateway server address cannot be empty".to_string());
        }

        // 验证路由配置
        for route in &self.gateway.routes {
            if route.path_prefix.is_empty() {
                return Err("Route path prefix cannot be empty".to_string());
            }
            if route.service_name.is_empty() {
                return Err("Route service name cannot be empty".to_string());
            }
        }

        Ok(())
    }

    /// 创建示例配置文件
    pub fn create_example_config() -> Self {
        let mut config = RustCloudConfig::default();
        
        config.application.name = "rustcloud-gateway".to_string();
        config.application.version = "1.0.0".to_string();
        config.application.port = 8080;
        
        config.gateway.server_addr = "0.0.0.0:8080".to_string();
        config.gateway.routes = vec![
            RouteConfig {
                path_prefix: "/api/v1/users".to_string(),
                service_name: "user-service".to_string(),
                rewrite_path: true,
                enable_cache: true,
                cache_ttl: 300,
            },
            RouteConfig {
                path_prefix: "/api/v1/orders".to_string(),
                service_name: "order-service".to_string(),
                rewrite_path: true,
                enable_cache: false,
                cache_ttl: 60,
            },
            RouteConfig {
                path_prefix: "/api/v1/products".to_string(),
                service_name: "product-service".to_string(),
                rewrite_path: true,
                enable_cache: true,
                cache_ttl: 600,
            },
        ];
        
        config.gateway.filters.auth.enabled = true;
        config.gateway.filters.auth.api_key_required = true;
        
        config.gateway.filters.rate_limit.enabled = true;
        config.gateway.filters.rate_limit.requests_per_minute = 1000;
        config.gateway.filters.rate_limit.burst_size = 100;
        
        config
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_config_validation() {
        let config = RustCloudConfig::default();
        assert!(config.validate().is_ok());

        let mut invalid_config = config.clone();
        invalid_config.application.name = "".to_string();
        assert!(invalid_config.validate().is_err());
    }

    #[test]
    fn test_config_serialization() {
        let config = RustCloudConfig::create_example_config();
        let yaml = serde_yaml::to_string(&config).unwrap();
        let deserialized: RustCloudConfig = serde_yaml::from_str(&yaml).unwrap();
        
        assert_eq!(config.application.name, deserialized.application.name);
        assert_eq!(config.gateway.routes.len(), deserialized.gateway.routes.len());
    }

    #[test]
    fn test_route_config() {
        let route = RouteConfig {
            path_prefix: "/api/users".to_string(),
            service_name: "user-service".to_string(),
            rewrite_path: true,
            enable_cache: true,
            cache_ttl: 300,
        };

        assert_eq!(route.path_prefix, "/api/users");
        assert_eq!(route.service_name, "user-service");
        assert!(route.rewrite_path);
        assert!(route.enable_cache);
        assert_eq!(route.cache_ttl, 300);
    }
}